#include "TcpConnect.h"

InetAddress TcpConnect::getLocal() const
{
    sockaddr_in addr{};
    socklen_t len = sizeof(addr);
    int ret = ::getsockname(_cltFd, (sockaddr *)&addr, &len);
    ERR_CHECK(ret, -1, "getLocal");

    return addr;
}

InetAddress TcpConnect::getPeer() const
{
    sockaddr_in addr{};
    socklen_t len = sizeof(addr);
    int ret = ::getpeername(_cltFd, (sockaddr *)&addr, &len);
    ERR_CHECK(ret, -1, "getLocal");

    return addr;
}

TcpConnect::TcpConnect(int fd, EventLoop *loop)
    : _cltFd{fd}, _io{fd}, _local{getLocal()}, _peer{getPeer()}, _loop{loop}
{
}

// TcpConnect::TcpConnect(const TcpConnect &conn)
//     : _cltFd(conn._cltFd), _io(conn._cltFd), _local(getLocal()), _peer(getPeer())
// {
// }

void TcpConnect::write(const char *str)
{
    _io.writen(str, strlen(str));
}

string TcpConnect::read()
{
    char buf[65535];
    _io.readLine(buf, sizeof(buf));

    return buf;
}

string TcpConnect::toString() const
{
    ostringstream oss;
    oss << _local.ip() << ": "
        << _local.port() << " -----> "
        << _peer.ip() << ": "
        << _peer.port();

    return oss.str();
}

void TcpConnect::setConnectCallback(Callback cb)
{
    _handleConnectCb = std::move(cb);
}
void TcpConnect::setHandleMessageCallback(Callback cb)
{
    _handleMessageCb = std::move(cb);
}
void TcpConnect::setCloseCallback(Callback cb)
{
    _handleClosedCb = std::move(cb);
}

void TcpConnect::handleConnect()
{
    _handleConnectCb(shared_from_this());
}
void TcpConnect::handleMessage()
{
    _handleMessageCb(shared_from_this());
}
void TcpConnect::handleClose()
{
    _handleClosedCb(shared_from_this());
}

string TcpConnect::peerIp() const
{
    return _peer.ip();
}

unsigned short TcpConnect::peerPort() const
{
    return _peer.port();
}

void TcpConnect::sendInLoop(string &msg)
{
    if (_loop)
    {
        _loop->runInLoop(std::bind(&TcpConnect::write, this, msg.c_str()));
    }
}